/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "stub.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gmock/gmock-actions.h"
#include "CommonJobFactory.h"
#include "PluginTypes.h"
#include "SnapshotBackup.h"
#include "PluginServiceCommon.h"
#include "JsonHelper.h"
#include "PluginServiceCommon.h"

using ::testing::_;
using ::testing::AtLeast;
using testing::DoAll;
using testing::InitGoogleMock;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgReferee;
using ::testing::Throw;

using namespace std;
using namespace Module;

namespace{
    const std::string NAS_SHARE_STR = "NasShare";
    const std::string NAS_FILESYSTEM_STR = "NasFileSystem";
    constexpr auto FLR_RESTORE_TYPE_ORIGIN_VALUE = "original";
    const std::string FILESET_STR = "Fileset";
}

enum class AppType1 {
        APPTYPE_NONE = 0,
        APPTYPE_FILESET,
        APPTYPE_ARCHIVE_RESTORE
    };

class CommonJobFactoryTest : public testing::Test {
public:
    void SetUp();
    void TearDown();
    static void SetUpTestCase();
    static void TearDownTestCase();
    Stub stub;
};

void CommonJobFactoryTest::SetUp(){
}

void CommonJobFactoryTest::TearDown(){}

void CommonJobFactoryTest::SetUpTestCase(){}

void CommonJobFactoryTest::TearDownTestCase(){}

/*
* 用例名称：AppInit
* 前置条件：无
* check点：获取App类型
*/
TEST_F(CommonJobFactoryTest, GetAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    JobType jobType = JobType::BACKUP;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_NONE));

    jobType = JobType::RESTORE;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_NONE));

    jobType = JobType::DELCOPY;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_SNAPSHOT));

    jobType = JobType::INDEX;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_NONE));

    jobType = JobType::LIVEMOUNT;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_NONE));

    jobType = JobType::CANCELLIVEMOUNT;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetAppType(jobCommonInfo, jobType), static_cast<uint64_t>(APPTYPE_NONE));
}

/*
* 用例名称：GetBackupAppType
* 前置条件：无
* check点：获取BackApp类型
*/
TEST_F(CommonJobFactoryTest, GetBackupAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    std::shared_ptr<AppProtect::BackupJob> backupJobInfo = std::make_shared<AppProtect::BackupJob>();

    std::vector<ApplicationEnvironment> AgentList;
    ApplicationEnvironment test1;
    test1.id = "111";
    ApplicationEnvironment test2;
    test2.id = "222";
    AgentList.push_back(test1);
    AgentList.push_back(test2);

    backupJobInfo->protectEnv.nodes = AgentList;
    backupJobInfo->extendInfo = "{\"slave_node_first\":\"1\"}";
    backupJobInfo->protectObject.subType = "Dameng";
    backupJobInfo->protectEnv.extendInfo = "{\"deployType\":\"1\"}";
    backupJobInfo->jobParam.backupType = AppProtect::BackupJobType::SNAPSHOT;
    jobCommonInfo->SetJobInfo(backupJobInfo);
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetBackupAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_SNAPSHOT));


    backupJobInfo->jobParam.backupType = AppProtect::BackupJobType::FULL_BACKUP;
    backupJobInfo->protectObject.subType = NAS_FILESYSTEM_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetBackupAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_REPLICATION));

    backupJobInfo->jobParam.backupType = AppProtect::BackupJobType::FULL_BACKUP;
    backupJobInfo->protectObject.subType = NAS_SHARE_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetBackupAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_SHARE));

    backupJobInfo->jobParam.backupType = AppProtect::BackupJobType::FULL_BACKUP;
    backupJobInfo->protectObject.subType = "";
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetBackupAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_NONE));

}

/*
* 用例名称：GetRestoreAppType
* 前置条件：无
* check点：获取Restore类型
*/
TEST_F(CommonJobFactoryTest, GetRestoreAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    std::shared_ptr<AppProtect::RestoreJob> backupJobInfo = std::make_shared<AppProtect::RestoreJob>();

    AppProtect::Copy copy;
    copy.dataType  = AppProtect::CopyDataType::SNAPSHOT_COPY;
    backupJobInfo->copies.push_back(copy);
    jobCommonInfo->SetJobInfo(backupJobInfo);
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_SNAPSHOT));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::CLOUD_STORAGE_COPY;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_ARCHIVE));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->jobParam.restoreType = RestoreJobType::type::FINE_GRAINED_RESTORE;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_FLR));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::TAPE_STORAGE_COPY;
    backupJobInfo->jobParam.restoreType = RestoreJobType::type::NORMAL_RESTORE;
    backupJobInfo->targetObject.subType = NAS_FILESYSTEM_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_ARCHIVE));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->targetObject.subType = NAS_FILESYSTEM_STR;
    backupJobInfo->extendInfo = "";
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_REPLICATION));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->targetObject.subType = NAS_FILESYSTEM_STR;
    FlrRestoreExtend flrExtend;
    flrExtend.targetLocation = FLR_RESTORE_TYPE_ORIGIN_VALUE;
    JsonHelper::StructToJsonString(flrExtend, backupJobInfo->extendInfo);
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_REPLICATION));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->targetObject.subType = NAS_FILESYSTEM_STR;
    flrExtend.targetLocation = "11";
    JsonHelper::StructToJsonString(flrExtend, backupJobInfo->extendInfo);
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_FLR));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->copies[0].protectObject.subType = NAS_FILESYSTEM_STR;
    backupJobInfo->targetObject.subType = NAS_SHARE_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_FLR));

    backupJobInfo->copies[0].dataType = AppProtect::CopyDataType::FULL_COPY;
    backupJobInfo->copies[0].protectObject.subType = "111";
    backupJobInfo->targetObject.subType = NAS_SHARE_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_SHARE));

    backupJobInfo->targetObject.subType = "other";
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetRestoreAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_NONE));

}

/*
* 用例名称：GetDelCopyAppType
* 前置条件：无
* check点：获取DelCopyApp类型
*/
TEST_F(CommonJobFactoryTest, GetDelCopyAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetDelCopyAppType(jobCommonInfo), static_cast<uint64_t>(APPTYPE_SNAPSHOT));

    
}

/*
* 用例名称：GetLivemountAppType
* 前置条件：无
* check点：获取LivemountApp类型
*/
TEST_F(CommonJobFactoryTest, GetLivemountAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetLivemountAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_NONE));

    std::shared_ptr<AppProtect::LivemountJob> livemountJob = make_shared<AppProtect::LivemountJob>();
    jobCommonInfo->SetJobInfo(livemountJob);
    livemountJob->targetObject.subType = NAS_SHARE_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetLivemountAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_SHARE));

    livemountJob->targetObject.subType = NAS_FILESYSTEM_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetLivemountAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_REPLICATION));

    livemountJob->targetObject.subType = "1111";
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetLivemountAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_NONE));
}

/*
* 用例名称：GetIndexAppType
* 前置条件：无
* check点：获取IndexApp类型
*/
TEST_F(CommonJobFactoryTest, GetIndexAppType)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetIndexAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_NONE));

    std::shared_ptr<AppProtect::BuildIndexJob> livemountJob = make_shared<AppProtect::BuildIndexJob>();
    jobCommonInfo->SetJobInfo(livemountJob);
    livemountJob->indexProtectObject.subType = NAS_SHARE_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetIndexAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_INDEX));

    livemountJob->indexProtectObject.subType = NAS_FILESYSTEM_STR;
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetIndexAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_INDEX));

    livemountJob->indexProtectObject.subType = "1111";
    EXPECT_EQ(CommonJobFactory::GetInstance()->GetIndexAppType(jobCommonInfo), static_cast<uint64_t>(AppType::APPTYPE_NONE));
}

/*
* 用例名称：CreateJob
* 前置条件：无
* check点：创建任务
*/
TEST_F(CommonJobFactoryTest, CreateJob)
{
    shared_ptr<JobCommonInfo> jobCommonInfo = make_shared<JobCommonInfo>();
    std::shared_ptr<AppProtect::BackupJob> backupJobInfo = std::make_shared<AppProtect::BackupJob>();
    backupJobInfo->protectObject.subType = FILESET_STR;
    backupJobInfo->extendInfo = "{\"slave_node_first\":\"1\"}";
    backupJobInfo->protectEnv.extendInfo = "{\"deployType\":\"1\"}";
    jobCommonInfo->SetJobInfo(backupJobInfo);
    CommonJobFactory::GetInstance()->CreateJob(jobCommonInfo, JobType::BACKUP);
    EXPECT_EQ(0, 0);

}

/*
* 用例名称：CreateFactoryJob
* 前置条件：无
* check点：创建工厂任务
*/
TEST_F(CommonJobFactoryTest, CreateFactoryJob)
{

    std::shared_ptr<JobCommonInfo> jobCommonInfo = std::make_shared<JobCommonInfo>();

    CommonJobFactory commonJobFactory;

    std::shared_ptr<AppProtect::BackupJob> backupJobInfo = std::make_shared<AppProtect::BackupJob>();

    std::vector<ApplicationEnvironment> AgentList;
    ApplicationEnvironment test1;
    test1.id = "111";
    ApplicationEnvironment test2;
    test2.id = "222";
    AgentList.push_back(test1);
    AgentList.push_back(test2);

    backupJobInfo->protectEnv.nodes = AgentList;
    backupJobInfo->extendInfo = "{\"slave_node_first\":\"1\"}";
    backupJobInfo->protectObject.subType = "Dameng";
    backupJobInfo->protectEnv.extendInfo = "{\"deployType\":\"1\"}";
    std::shared_ptr<ThriftDataBase> data = std::dynamic_pointer_cast<ThriftDataBase>(backupJobInfo);
    jobCommonInfo->SetJobInfo(data);
    
    EXPECT_NE(commonJobFactory.CreateFactoryJob<SnapshotBackup>(jobCommonInfo), nullptr);
}